#ifndef SOCKET_H
#define SOCKET_H

#include <iostream>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")
#define maxLength 1048576

using namespace std;

bool TCPinit(){ // for Server and Client
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested = MAKEWORD(2, 2);
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err)
        return false;
    if (wsaData.wVersion != MAKEWORD(2, 2)){
        WSACleanup();
        return false;
    }
    return true;
}

SOCKET TCPopen(int port){ // for Server
    SOCKET sockSer = socket(AF_INET, SOCK_STREAM, 0);
    SOCKADDR_IN addrSer;
    addrSer.sin_family = AF_INET;
    addrSer.sin_port = htons(port);
    addrSer.sin_addr.s_addr = htonl(INADDR_ANY);
    bind(sockSer, (SOCKADDR *)&addrSer, sizeof(SOCKADDR));
    listen(sockSer, 5);
    return sockSer;
}

SOCKET TCPconnect(int port, char* ip){ // for Client
    SOCKET sockCli = socket(AF_INET, SOCK_STREAM, 0);
    SOCKADDR_IN addrSer;
    addrSer.sin_family = AF_INET;
    addrSer.sin_port = htons(port);
    addrSer.sin_addr.s_addr = inet_addr(ip);
    connect(sockCli, (SOCKADDR*)&addrSer, sizeof(SOCKADDR));
    return sockCli;
}

struct Conn{ // for Server
    bool success;
    SOCKET sockConn;
    SOCKADDR_IN addrCli;
    int len;
};

Conn TCPaccept(SOCKET sockSer){ // for Server
    Conn a;
    a.len = sizeof(SOCKADDR);
    a.sockConn = accept(sockSer, (SOCKADDR*)&a.addrCli, &a.len);
    a.success = (a.sockConn != INVALID_SOCKET);
    return a;
}

char buf[maxLength];

void TCPsend(Conn conn, char* msg){ // for Server
    send(conn.sockConn, msg, strlen(msg) + 1, 0); // +1 for '\0'
}

void TCPsend(SOCKET sockCli, char* msg){ // for Client
    send(sockCli, msg, strlen(msg) + 1, 0);
}

char* TCPrecv(Conn conn){
    recv(conn.sockConn, buf, maxLength, 0);
    return buf;
}

char* TCPrecv(SOCKET sockCli){ // for Client
    recv(sockCli, buf, maxLength, 0);
    return buf;
}

void TCPdisconnect(Conn conn){
	closesocket(conn.sockConn);
}

void TCPdisconnect(SOCKET sockCli){ // for Client
    closesocket(sockCli);
}

void TCPclose(){ // for Server and Client
    WSACleanup();
}

#endif
